var agr = agr || {};

// {{page:$obj, prevPage:string, nextPage:string, editPage:string, 
//	 model:{obj:dbObj,fn:function},title:string, noBack:bool,
//	 noEdit:bool,noNew:bool,selectNum:number,noDelete:bool}} props
agr.ListViewPage = function(props) {
	'use strict';
 	props = props || {};
	var listPage = {};
	var state = agr.Interface.getStateFromURL(props.page.prop('baseURI'));

	var getState = function(id) {
		state[props.model.obj.name + 'ID'] = id;
		return state;
	};
	//START Create the DOM elements to pass to header and listview
	var $header = $('<div/>', {
		'data-role' : 'header'
	})
	var $a_left = $('<a/>', {
		'data-role' : 'button',
		'data-icon' : 'back',
		html : 'Back'
	})
	var $h1_title = $('<h1/>', {
		html : props.title
	})
	var $a_right = $('<a/>', {
		'data-role' : 'button',
		'data-icon' : 'gear',
		html : 'Edit'
	})
	$header.append($a_left, $h1_title, $a_right);
	props.page.append($header);

	var $div_list = $('<div/>', {
		'data-role' : 'content',
        'style' : 'display:none'
	});

	var $ul = $('<ul/>', {
		'data-role' : 'listview',
		'data-split-icon' : 'delete',
		'data-split-theme' : 'c'
	});
	$div_list.append($ul);
	props.page.append($div_list);

	var $div_select = $('<div/>', {
		'data-role' : 'content',
        'style' : 'display:none'
	});
	var $select = $('<select/>');

    var $a_delete = $('<a/>', {
        'data-icon' : 'delete',
        'data-role' : 'button',
        'html' : 'Delete',
        'style' : 'display:none'
    });

	$div_select.append($select);
	props.page.append($div_select);

	if(!props.noNew) {
		var $footer = $('<div/>', {
			'data-role' : 'footer'
			//'class' : 'ui-bar',
            //'data-position' : 'inline'
			//'data-position' : 'fixed'
		})
		var $a_new = $('<a/>', {
			'data-role' : 'button',
			'data-icon' : 'plus',
			html : 'New'//,
			//href : agr.Interface.makeQueryURL(props.editPage, getState())
		});

        $a_new.css('margin-top', '5px');
        $a_new.css('margin-bottom', '5px');
        $a_new.css('margin-left', '10px');
        $a_new.css('margin-right', '50px');

        $a_new.click(function() {
            $.mobile.changePage(agr.Interface
                .makeQueryURL(props.editPage, getState()))
        });

		$footer.append($a_new);
		if(!props.noDelete){
			$footer.append($a_delete);
		}
		props.page.append($footer);
	}
	//END creating dom elements on page

	var listView;
	var header;
	var selectNum = (props.selectNum) ? props.selectNum : 15;
	var edit;
	var deleteNext; 

	props.page.unbind('pagebeforeshow.ListViewPage');

	props.page.bind('pagebeforeshow.ListViewPage', function(evt, data) {

		listView = agr.ListView($ul);
		header = new agr.Header($a_left, $h1_title, $a_right);
		header.showEdit();

		if(props.noEdit) {
			header.hideRight();
		}

		if(props.noBack) {
			header.hideLeft();
		}

		header.clickLeft(function() {
			if(header.leftCancel()) {
				listView.editOff();
				var editResults = listView.dump();
				var i;
				for(i in editResults) {
					if(editResults[i].active == false) {
						editResults[i].active = true;
					}
				}
				listView.load(editResults);
				header.showEdit();
				if(props.noBack) {
					header.hideLeft();
				}
				} else {//back
				$.mobile.changePage(
                    agr.Interface.makeQueryURL(props.prevPage, state),
                    {reverse:true});
			}
		});
		
	
		header.clickRight(function() {
			if(header.rightDone()) {
				listView.editOff();
				edit=false;
				header.showEdit();
				if(props.noBack) {
					header.hideLeft();
				}
				$.each(listView.dump(), function(k, v) {
					if(!v.active) {
						// TODO transaction or something, bug Doug
						props.model.obj.remove(v.dbObj, function() {
						}, HandleError);
					}
				});
			} else {//edit
				listView.editOn(props.noDelete);
				edit=true;
				header.showDone();
				header.showLeft();
			}
		});

		props.page.unbind('pagehide.ListViewPage');

		props.page.bind('pagehide.ListViewPage', function(evt) {
			header.showEdit();
			listView.edit = false;
		});
		if(!props.model.fn) {
            var parentid;
            if (props.model.obj.parent) {
                parentid = {};
                parentid[props.model.obj.parent.name] =
                    state[props.model.obj.parent.name + 'ID'];
            }
            props.model.obj.list(
                    parentid,
                    listPage.load,
                    HandleError);
		} else {
			props.model.fn(props.model.obj, listPage, state);
		}
	});
	if(!props.noNew && !props.noDelete){
		$a_delete.click(function(){deleteNext = true;});
	}

	var mainForm,secondForm,asideForm,bubbleForm;
	var doFormat = function(dbObj) {
		var $div_html;
		dbObj.text = "";
		if(mainForm){
			var mainText;
			if(mainForm.constructor === 'String'){
				mainText = mainForm;
			}
			else{
				mainText = mainForm(dbObj);	
			}
			dbObj.text = mainText;
			$div_html = $('<div/>');
			$div_html.append($('<h3/>',{
				"class" : "ui-li-heading",
				html : mainText
			}))
		}
		if(secondForm){
			var secondText;
			if(secondForm.constructor === 'String'){
				secondText = secondForm;
			}
			else{
				secondText = secondForm(dbObj);	
			}
			dbObj.text = dbObj.text +" "+secondText;
			$div_html = $div_html || $('<div/>');
			$div_html.append($('<p/>',{
				"class" : "ui-li-desc",
				html : secondText
			}))
		}
		if(asideForm){
			var asideText;
			if(asideForm.constructor === 'String'){
				asideText = asideForm;
			}
			else{
				asideText = asideForm(dbObj);	
			}
			dbObj.text = dbObj.text +" "+asideText;
			$div_html = $div_html || $('<div/>');
			$div_html.append($('<p/>',{
				"class" : "ui-li-aside",
				html : asideText
			}))
		}
		if(bubbleForm){
			var bubbleText;
			if(bubbleForm.constructor === 'String'){
				bubbleText = bubbleForm;
			}
			else{
				bubbleText = bubbleForm(dbObj);	
			}
			dbObj.text = dbObj.text +" Count: "+ bubbleText;
			$div_html = $div_html || $('<div/>');
			$div_html.append($('<span/>',{
				"class" : "ui-li-count",
				html : bubbleText
			}))
		}
		if($div_html) {
			dbObj.html = $div_html;
		}
		else{ //formatters were not set
			if(dbObj.Name) {
				dbObj.html = dbObj.Name;
				dbObj.text = dbObj.Name;
			
			} else {
				dbObj.html = dbObj.ID;
				dbObj.text = dbObj.ID;	
			}
		}
		return dbObj;
	}
	/**
	 * {{mainText:fn(dbObj),secondText:fn(dbObj),asideText:fn(dbObj),bubbleText:fn(dbObj)}}
	 */
	listPage.setFormat = function(args){
		mainForm = args.mainText;
		secondForm = args.secondText;
		asideForm = args.asideText;
		bubbleForm = args.bubbleText;
		
	}
	var go = function(){
		$select.change(function(){});
		
		if(deleteNext){
			deleteNext=false;
			var deleteID = $select.val();
			var sure = confirm("Are you sure you wish to delete "+$select.find('option[value='+deleteID+']').html()+"?");
            		if(sure){
            			$select.find('option[value='+deleteID+']').remove();
				props.model.obj.remove({'ID':parseInt(deleteID)}, function(){ 
					}, HandleError);
				$select.selectmenu("refresh");
			}
		}
		else if(edit){
			$.mobile.changePage(agr.Interface.makeQueryURL(props.editPage,getState($select.val())));
		}
		else{
			$.mobile.changePage(agr.Interface.makeQueryURL(props.nextPage,getState($select.val())));
		}
	}
	
	var qualifyList = function(list) {
		var reducedList = new Array();
		var i;
		var x = 0;
		if(state.Qualify) {
			for(i in list) {
				if(list[i][state.Qualify.field] == state.Qualify.value) {
					reducedList[x] = list[i];
					x++;
				}
			}
			state.Qualify = null;
			return reducedList;
		}
		return list;
	}
	
	/**
	 * Populates the ListView portion of page with contents of list.
	 *
	 * @param {array} list array of database objects, set html:String for labels
	 * or it will default to the Name or Tag of the object.
	 */
	listPage.load = function(list) {

		list = qualifyList(list);

        var i;
        for (i in list) {
            list[i] = doFormat(list[i]);
        }

        if (list.length > selectNum) {
            listPage.loadSelect(list);
        } else {
            listPage.loadList(list);
        }
	}

    listPage.loadSelect = function(list) {
		var i,
            inner = "<option></option>";
		for(i in list) {
            inner = loadSelect(list[i], inner);
		}
		if(!props.noNew) {
			inner = inner + "<option value=''>New</option>"
		}
        $select.html(inner);
        $select.change(go);
        listPage.showSelect();
    }

    listPage.showSelect = function() {
        $select.selectmenu("refresh");
	    $a_delete.css('display','');
        $div_list.css('display','none');
        $div_select.css('display','block');
    }

    listPage.loadList = function(list) {
		var i;

		listView.performOn();
		for(i in list) {
            loadListView(list[i]);
		}
		listView.performOff();

        listPage.showList();
    }

    listPage.showList = function() {
        listView.render();

        $div_select.css('display','none');
        $div_list.css('display','block');
    }

	var loadListView = function(obj) {
		listView.addListItem({
			uid : obj.ID,
			html : obj.html,
			href : agr.Interface.makeQueryURL(props.nextPage, getState(obj.ID)),
			edithref : agr.Interface.makeQueryURL(props.editPage, getState(obj.ID)),
			dbObj : obj
		});
	}
	var loadSelect = function(obj, inner) {
		return inner + "<option value=" + obj.ID + ">" + obj.text + "</option>";
	}
	/**
	 * For when NOT using editmode & etc.
	 * ie for ColonyMenu
	 */
	listPage.addListItem = function(item) {
		//item = doFormat(item);
		if(props.noEdit) {
			listView.addListItem(item);
		}
	}
	/**
	 * calls headers setTitle
	 *
	 */
	listPage.setTitle = function(title) {
		header.setTitle(title);
	}
	return listPage;
}
